package org.estela.util;


import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Small Map is a Map implementation for tiny maps.<p>
 * 
 * This map is just useful if entries size is around 7
 * <p>
 *
 * @since 1.00
 * @version $Revision$
 */
public final class SmallMap<K,V> implements Map<K,V>, Serializable{

	private static final long serialVersionUID = 1L;
	
	/** Entries */
	private List _entries = new LinkedList();
	
	/**
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		Iterator it = _entries.iterator();
		StringBuffer buff = new StringBuffer();
		buff.append("[");
		while (it.hasNext()) {
			buff.append("\n\t").append( Arrays.toString((Object[])it.next()) );
		}
		buff.append("]");		
		return buff.toString();
	}
	
	/**
	 * @see java.util.Map#size()
	 */
	public int size() {
		return _entries.size();
	}

	/**
	 * @see java.util.Map#isEmpty()
	 */
	public boolean isEmpty() {
		return _entries.size() == 0;
	}

	/**
	 * @see java.util.Map#containsKey(java.lang.Object)
	 */
	public boolean containsKey(Object key) {
		int size = _entries.size();
		for(int i=0;i<size;i++) {
			Object[] entry = (Object[]) _entries.get(i);
			if (entry[0].equals(key)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * @see java.util.Map#containsValue(java.lang.Object)
	 */
	public boolean containsValue(Object value) {
		int size = _entries.size();
		for(int i=0;i<size;i++) {
			Object[] entry = (Object[]) _entries.get(i);
			if (entry[1].equals(value)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * @see java.util.Map#get(java.lang.Object)
	 */
	public V get(Object key) {
		int size = _entries.size();
		for(int i=0;i<size;i++) {
			Object[] entry = (Object[]) _entries.get(i);
			if (entry[0].equals(key)) {
				return (V) entry[1];
			}
		}
		return null;
	}
	
	/**
	 * @see java.util.Map#put(K, V)
	 */
	public V put(K key, V value) {
		int size = _entries.size();
		for(int i=0;i<size;i++) {
			if (key.equals( ((Object[]) _entries.get(i))[0]) ) {
				_entries.set(i,  new Object[] {key, value});
				return value;
			}
		}
		_entries.add(new Object[] {key, value});
		return value;
	}

	/**
	 * @see java.util.Map#remove(java.lang.Object)
	 */
	public V remove(Object key) {
		int size = _entries.size();
		for(int i=0;i<size;i++) {
			Object[] entry = (Object[]) _entries.get(i);
			if (entry[0].equals(key)) {
				_entries.remove(i);
				return (V) entry;
			}
		}
		return null;
	}

	/**
	 * @see java.util.Map#clear()
	 */
	public void clear() {
		_entries.clear();
	}

	/**
	 * @see java.util.Map#putAll(Map)
	 */
	public void putAll(Map t) {
		if (t == null) {
			throw new NullPointerException("Parameter map is null.");
		}
		if (t instanceof SmallMap) {
			SmallMap other = (SmallMap) t;
			_entries.addAll(other._entries);
			return;
		}
		throw new UnsupportedOperationException("not implemented yet.");
	}

	/**
	 * Not implemented.
	 */
	public Set keySet() {
		HashSet set = new HashSet(_entries);
		Object obj;
		for(Iterator it = _entries.iterator();it.hasNext();) {
			set.add( obj = ((Object[])it.next())[1] );
			System.out.println(obj.getClass());
		}
		return set;
	}

	/**
	 * Not implemented.
	 */
	public Collection values() {
		throw new UnsupportedOperationException("not implemented yet.");			
	}

	/**
	 * Not implemented.
	 */
	public Set entrySet() {
		throw new UnsupportedOperationException("not implemented yet.");
	}	
}
